#include "terra-ge/terra-ge.h"
#include "terra-ge/game/game.h"
#include "terra-ge/render/vobject_complex.h"
#include "terra-ge/render/light.h"

using namespace TerraGE;

ALLEGRO_FONT *font;

list<VObject *> vobjects;
list<Light *> lights;
Light *directional;
Camera *cam;

VObject_Complex *pilar;
int debug_mode;

void MainGame_Start(void *instance) {
    Game *gInstance = (Game *) instance;

    lights.push_back(new Light(0, 50, 10, 300, 0.5, 1.5, 1.5));
    lights.push_back(new Light(0, 100, 10, 300, 1.2, 1, 0.8));

    directional = new Light(1, 1.3, 1, 300, 1, 1, 1);
    directional->Set_Strength(1);
    directional->Set_Ambience(.4);

    font = al_load_font("assets/font/GameFont.ttf", 16, 0);

    cam = new Camera();
    cam->Set_Map_Width(2400);
    cam->Set_Map_Height(2400);
    cam->Set_Map_Tall(2400);

    pilar = new VObject_Complex("pilar", 150, 150, 0, 1);

    vobjects.push_back(pilar);
    vobjects.push_back(new VObject_Complex("house", 1000, 1000, 0));

    vobjects.push_back(new VObject_Complex("teapot", 1600, 1600, 0));

    debug_mode=0;
}


void MainGame_Close(void *instance) {
    Game *gInstance = (Game *) instance;

}



void MainGame_Update(void *instance, float timestep) {
    Game *gInstance = (Game *) instance;

    if (KB_Input[ALLEGRO_KEY_ESCAPE]) gInstance->Set_Scene("");

    if (KB_Active[ALLEGRO_KEY_MOUSE_RCLICK]) {
        Vec2D pos;
        pos = cam->Screen_To_Proj(mouse_x+cam->Get_X(), mouse_y+cam->Get_Y());
        pos = cam->Snap_To_Map(pos);

        pilar->Set_X(pos.x);
        pilar->Set_Y(pos.y);
    }

    if (KB_Active[ALLEGRO_KEY_MOUSE_LCLICK]) {
        Vec2D pos;
        pos = cam->Screen_To_Proj(mouse_x+cam->Get_X(), mouse_y+cam->Get_Y());
        pos = cam->Snap_To_Map(pos);

        (*lights.begin())->Set_X(pos.x);
        (*lights.begin())->Set_Y(pos.y);
    }

    float tz;
    tz = (*lights.begin())->Get_Z();
    if (KB_Active[ALLEGRO_KEY_W]) (*lights.begin())->Set_Z(tz+timestep*5);
    if (KB_Active[ALLEGRO_KEY_S]) (*lights.begin())->Set_Z(tz-timestep*5);

    tz = pilar->Get_Z();
    if (tz < 0) tz = 0;
    if (KB_Active[ALLEGRO_KEY_A]) pilar->Set_Z(tz+timestep*5);
    if (KB_Active[ALLEGRO_KEY_Q]) pilar->Set_Z(tz-timestep*5);

    for (list<Light *>::iterator it=lights.begin(); it!=lights.end(); it++) (*it)->Update(timestep);

    if (KB_Active[ALLEGRO_KEY_LEFT]) cam->Move_Target_X(-5*timestep);
    if (KB_Active[ALLEGRO_KEY_UP]) cam->Move_Target_Y(-5*timestep);
    if (KB_Active[ALLEGRO_KEY_RIGHT]) cam->Move_Target_X(5*timestep);
    if (KB_Active[ALLEGRO_KEY_DOWN]) cam->Move_Target_Y(5*timestep);


    if (KB_Input[ALLEGRO_KEY_F1]) debug_mode += 1;
    if (debug_mode >= DEBUG_SIZE) debug_mode = 0;


    cam->Update(timestep);
}


void get_gl_size(int &width, int &height)
{
    int iv[4];
    glGetIntegerv(GL_VIEWPORT, iv);
    width = iv[2];
    height = iv[3];
}


void visualize_depth_buffer()
{
    int width, height;

    get_gl_size(width, height);

    float *data = new float[width * height];

    glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data);
    glDrawPixels(width, height, GL_LUMINANCE, GL_FLOAT, data);

    delete [] data;
}

void MainGame_Draw(void *instance) {
    Game *gInstance = (Game *) instance;
    al_clear_to_color(al_map_rgb(100, 100, 100));


    gInstance->Get_First_Renderer()->Render(&vobjects, &lights, directional, cam, debug_mode);


    if (KB_Active[ALLEGRO_KEY_D]) visualize_depth_buffer();
}
